﻿using DeviceFaultPushService.DeviceProcessManagement.CommunicationManagement.ModbusTcp.Models;
using DeviceFaultPushService.DeviceProcessManagement.CommunicationManagement.Models;
using DeviceFaultPushService.MessagePushService.Models;
using DeviceFaultPushService.SystemService;
using NModbus;
using OfficeOpenXml;
using S7.Net;
using System.Collections;
using System.Net.Sockets;
using System.Text.Encodings.Web;
using System.Text.Json;

namespace 设备报警推送服务
{
    public partial class 设备添加与调整 : Form
    {
        public 设备添加与调整()
        {
            InitializeComponent();
        }

        public string conf = "";

        public 设备添加与调整(string conf)
        {
            InitializeComponent();
            this.conf = conf;
        }
        bool IsInitialization = false;

        #region 显示行号
        private void dtLineHCurvePara_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            var grid = sender as DataGridView;
            var rowidx = (e.RowIndex).ToString();
            var centerFormat = new StringFormat()
            {
                Alignment = StringAlignment.Center,
                LineAlignment = StringAlignment.Center
            };
            var headerBuunds = new Rectangle(e.RowBounds.Left, e.RowBounds.Top, grid!.RowHeadersWidth, e.RowBounds.Height);
            e.Graphics.DrawString(rowidx, new Font("宋体", 11), SystemBrushes.ControlText, headerBuunds, centerFormat);
        }
        #endregion
        private void 设备添加与调整_Load(object sender, EventArgs e)
        {
            cbProtocol.DataSource = Enum.GetNames(typeof(ProtocolEnum));
            //添加默认行
            dataGridView1.Rows.Add();
            dgvSiemensPlc.Rows.Add();
            dGVModbusTcp.Rows.Add();

            //设置DataGridView文本居中
            dataGridView1.RowsDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            //标题文字居中.
            dataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            //设置DataGridView文本居中
            dataGridView2.RowsDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            //标题文字居中.
            dataGridView2.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            //设置DataGridView文本居中
            dGVModbusTcp.RowsDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            //标题文字居中.
            dGVModbusTcp.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            //设置DataGridView文本居中
            dgvSiemensPlc.RowsDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            //标题文字居中.
            dgvSiemensPlc.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            //设置DataGridView文本居中
            dataGridView6.RowsDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            //标题文字居中.
            dataGridView6.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;

            Initialization();
        }

        /// <summary>
        /// 初始化
        /// </summary>
        private void Initialization()
        {
            //conf = File.ReadAllText($"json/10002.json");

            //传入设备id检查
            if (conf.Length > 2)
            {
                IsInitialization = true;
                //配置文件序列化
                DeviceFaultPushService.DeviceProcessManagement.CommunicationManagement.Models.DeviceInformationModel deviceInformation = JsonSerializer.Deserialize<DeviceFaultPushService.DeviceProcessManagement.CommunicationManagement.Models.DeviceInformationModel>(conf)!;
                //加载基础信息和联系人
                dataGridView1.Rows[0].Cells[0].Value = deviceInformation.Number;
                dataGridView1.Rows[0].Cells[1].Value = deviceInformation.Name;
                dataGridView2.Rows.Clear();
                if (deviceInformation.Contacts is not null)
                {
                    for (int i = 0; i < deviceInformation.Contacts.Count; i++)
                    {
                        int index = dataGridView2.Rows.Add();
                        dataGridView2.Rows[index].Cells[0].Value = deviceInformation.Contacts[i].PhoneNumber;
                        dataGridView2.Rows[index].Cells[1].Value = deviceInformation.Contacts[i].EnableSms;
                        dataGridView2.Rows[index].Cells[2].Value = deviceInformation.Contacts[i].EnableDialing;
                    }
                }
                //通过 通讯协议 序列化配置文件
                if (deviceInformation.Protocol == ProtocolEnum.SiemensS7)
                {
                    //加载通讯协议
                    cbProtocol.Text = ProtocolEnum.SiemensS7.ToString();
                    //序列化配置文件
                    DeviceFaultPushService.DeviceProcessManagement.CommunicationManagement.SiemensS7.Models.DeviceInformationModel deviceConf = JsonSerializer.Deserialize<DeviceFaultPushService.DeviceProcessManagement.CommunicationManagement.SiemensS7.Models.DeviceInformationModel>(conf)!;
                    //加载设备特有属性
                    dgvSiemensPlc.Rows[0].Cells[0].Value = deviceConf.DeviceAddress.CpuType.ToString();
                    dgvSiemensPlc.Rows[0].Cells[1].Value = deviceConf.DeviceAddress.Ip;
                    dgvSiemensPlc.Rows[0].Cells[2].Value = deviceConf.DeviceAddress.Port;
                    dgvSiemensPlc.Rows[0].Cells[3].Value = deviceConf.DeviceAddress.Rack;
                    dgvSiemensPlc.Rows[0].Cells[4].Value = deviceConf.DeviceAddress.Slot;
                    dgvSiemensPlc.Rows[0].Cells[5].Value = deviceConf.DeviceAddress.IsMultiple;

                    for (int i = 0; i < deviceConf.DataAddress.Count; i++)
                    {
                        int index = dataGridView6.Rows.Add();
                        dataGridView6.Rows[index].Cells[0].Value = deviceConf.DataAddress[i].AlarmAddress;
                        dataGridView6.Rows[index].Cells[1].Value = deviceConf.DataAddress[i].AlarmInformation;
                        dataGridView6.Rows[index].Cells[2].Value = deviceConf.DataAddress[i].IsEnable;
                    }
                }

                //通过 通讯协议 序列化配置文件
                if (deviceInformation.Protocol == ProtocolEnum.ModbusTcp)
                {
                    //加载通讯协议
                    cbProtocol.Text = ProtocolEnum.ModbusTcp.ToString();
                    //序列化配置文件
                    DeviceFaultPushService.DeviceProcessManagement.CommunicationManagement.ModbusTcp.Models.DeviceInformationModel deviceConf = JsonSerializer.Deserialize<DeviceFaultPushService.DeviceProcessManagement.CommunicationManagement.ModbusTcp.Models.DeviceInformationModel>(conf)!;
                    //加载设备特有属性

                    dGVModbusTcp.Rows[0].Cells[0].Value = deviceConf.DeviceAddress.Ip;
                    dGVModbusTcp.Rows[0].Cells[1].Value = deviceConf.DeviceAddress.Port;
                    if (deviceConf.DataAddress.FunctionCode == FunctionBlockEnum.Coils)
                    {
                        dGVModbusTcp.Rows[0].Cells[2].Value = "Coils";
                    }
                    if (deviceConf.DataAddress.FunctionCode == FunctionBlockEnum.Inputs)
                    {
                        dGVModbusTcp.Rows[0].Cells[2].Value = "Inputs";
                    }
                    //
                    dGVModbusTcp.Rows[0].Cells[3].Value = deviceConf.DataAddress.SlaveAddress;
                    dGVModbusTcp.Rows[0].Cells[4].Value = deviceConf.DataAddress.StartAddress;
                    dGVModbusTcp.Rows[0].Cells[5].Value = deviceConf.DataAddress.NumberOfPoints;
                    for (int i = 0; i < deviceConf.DataAddress.IsEnable.Count; i++)
                    {
                        int index = dataGridView6.Rows.Add();
                        dataGridView6.Rows[index].Cells[0].Value = deviceConf.DataAddress.StartAddress + i;
                        dataGridView6.Rows[index].Cells[1].Value = deviceConf.DataAddress.AlarmInformation[i];
                        dataGridView6.Rows[index].Cells[2].Value = deviceConf.DataAddress.IsEnable[i];
                    }
                }
            }
            else
            {
                ArrayList arrayList = ConfigService.GetID();

                if (arrayList is null || arrayList.Count < 1)
                {
                    dataGridView1.Rows[0].Cells[0].Value = 10000;
                }
                else
                {
                    int num = int.Parse(arrayList[arrayList.Count - 1]!.ToString()!)! + 1;
                    dataGridView1.Rows[0].Cells[0].Value = num;
                }
            }
        }

        private void cbProtocol_SelectedIndexChanged(object sender, EventArgs e)
        {
            dataGridView6.Columns[3].ReadOnly = true;
            dataGridView6.Rows.Clear();

            ProtocolEnum protocol = (ProtocolEnum)Enum.Parse(typeof(ProtocolEnum), cbProtocol.Text, true);
            if (protocol == ProtocolEnum.SiemensS7)
            {
                dGVModbusTcp.Visible = false;
                dgvSiemensPlc.Visible = true;
                dataGridView6.Columns[0].ReadOnly = false;
                dataGridView6.AllowUserToAddRows = true;
            }
            if (protocol == ProtocolEnum.ModbusTcp)
            {
                dGVModbusTcp.Visible = true;
                dgvSiemensPlc.Visible = false;
                // 禁止在 DataGridView 中添加新行  
                dataGridView6.AllowUserToAddRows = false;
                dataGridView6.Columns[0].ReadOnly = true;
                dataGridView6.Columns[1].ReadOnly = false;
            }
        }

        private void btnPreserve_Click(object sender, EventArgs e)
        {
            //退出验证服务
            Form form = new 验证服务();

            DialogResult dialogResult = form.ShowDialog();

            if (dialogResult != DialogResult.OK)
            {
                return;
            }
            ProtocolEnum protocol = (ProtocolEnum)Enum.Parse(typeof(ProtocolEnum), cbProtocol.Text, true);

            if (protocol == ProtocolEnum.SiemensS7)
            {
                DeviceFaultPushService.DeviceProcessManagement.CommunicationManagement.SiemensS7.ConfigurationGeneration configuration = new();
                configuration.GenerationDeviceInformation(iSNull(dataGridView1.Rows[0].Cells[0].Value), iSNull(dataGridView1.Rows[0].Cells[1].Value), cbProtocol.Text);
                //保存联系人
                for (int i = 0; i < dataGridView2.RowCount - 1; i++)
                {
                    string phoneNumber = iSNull(dataGridView2.Rows[i].Cells[0].Value);

                    if (phoneNumber.Length < 5)
                    {
                        continue;
                    }
                    string level = UserLevelEnum.User.ToString();
                    string enableSms = isNullBool(dataGridView2.Rows[i].Cells[1].Value);
                    string enableDialing = isNullBool(dataGridView2.Rows[i].Cells[2].Value);
                    configuration.GenerationContacts(phoneNumber, level, enableDialing, enableSms);
                }
                //保存设备信息
                string type = iSNull(dgvSiemensPlc.Rows[0].Cells[0].Value);
                string ip = iSNull(dgvSiemensPlc.Rows[0].Cells[1].Value);
                string port = iSNull(dgvSiemensPlc.Rows[0].Cells[2].Value);
                string rack = iSNull(dgvSiemensPlc.Rows[0].Cells[3].Value);
                string slot = iSNull(dgvSiemensPlc.Rows[0].Cells[4].Value);
                string isMultiple = isNullBool(dgvSiemensPlc.Rows[0].Cells[5].Value);
                configuration.GenerationDeviceAddress(type, ip, port, rack, slot, isMultiple);
                //保存数据信息
                for (int i = 0; i < dataGridView6.RowCount; i++)
                {
                    string alarmAddress = iSNull(dataGridView6.Rows[i].Cells[0].Value);

                    if (alarmAddress.Length < 3)
                    {
                        continue;
                    }
                    string alarmInformation = iSNull(dataGridView6.Rows[i].Cells[1].Value);
                    string isEnable = isNullBool(dataGridView6.Rows[i].Cells[2].Value);

                    configuration.GenerationDataAddress(alarmAddress, isEnable, alarmInformation);
                }

                var _deviceInformation = configuration.DeviceInformation;
                //添加数据地址信息
                string jsonString = JsonSerializer.Serialize(_deviceInformation, new JsonSerializerOptions()
                {
                    Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
                });

                // 检查文件夹是否存在  
                if (!Directory.Exists("json"))
                {
                    // 如果不存在，则创建文件夹  
                    Directory.CreateDirectory("json");
                }
                File.Delete($"json/{_deviceInformation.Number}.json");

                File.WriteAllText($"json/{_deviceInformation.Number}.json", jsonString);

                MessageBox.Show("添加成功");
            }

            if (protocol == ProtocolEnum.ModbusTcp)
            {
                DeviceFaultPushService.DeviceProcessManagement.CommunicationManagement.ModbusTcp.ConfigurationGeneration configuration = new();
                configuration.GenerationDeviceInformation(iSNull(dataGridView1.Rows[0].Cells[0].Value), iSNull(dataGridView1.Rows[0].Cells[1].Value), cbProtocol.Text);
                //保存联系人
                for (int i = 0; i < dataGridView2.RowCount - 1; i++)
                {
                    string phoneNumber = iSNull(dataGridView2.Rows[i].Cells[0].Value);

                    if (phoneNumber.Length < 5)
                    {
                        continue;
                    }
                    string level = UserLevelEnum.User.ToString();
                    string enableSms = isNullBool(dataGridView2.Rows[i].Cells[1].Value);
                    string enableDialing = isNullBool(dataGridView2.Rows[i].Cells[2].Value);
                    configuration.GenerationContacts(phoneNumber, level, enableDialing, enableSms);
                }
                //保存设备信息

                string ip = iSNull(dGVModbusTcp.Rows[0].Cells[0].Value);
                string port = iSNull(dGVModbusTcp.Rows[0].Cells[1].Value);
                configuration.GenerationDeviceAddress(ip, port);

                string functionCode = iSNull(dGVModbusTcp.Rows[0].Cells[2].Value);
                string slaveAddress = iSNull(dGVModbusTcp.Rows[0].Cells[3].Value);
                string startAddress = isNullBool(dGVModbusTcp.Rows[0].Cells[4].Value);
                string numberOfPoints = isNullBool(dGVModbusTcp.Rows[0].Cells[5].Value);

                configuration.GenerationDataAddress(functionCode, slaveAddress, startAddress, numberOfPoints);
                //保存数据信息
                List<bool> isEnable = new();
                List<string> alarmInformation = new();
                for (int i = 0; i < dataGridView6.RowCount; i++)
                {
                    isEnable.Add(bool.Parse(isNullBool(dataGridView6.Rows[i].Cells[2].Value)));
                    alarmInformation.Add(iSNull(dataGridView6.Rows[i].Cells[1].Value));
                }
                configuration.GenerationDataAddress(isEnable, alarmInformation);

                var _deviceInformation = configuration.deviceInformation;
                //添加数据地址信息
                string jsonString = JsonSerializer.Serialize(_deviceInformation, new JsonSerializerOptions()
                {
                    Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
                });

                // 检查文件夹是否存在  
                if (!Directory.Exists("json"))
                {
                    // 如果不存在，则创建文件夹  
                    Directory.CreateDirectory("json");
                }
                File.Delete($"json/{_deviceInformation.Number}.json");

                File.WriteAllText($"json/{_deviceInformation.Number}.json", jsonString);

                MessageBox.Show("添加成功");
            }
        }

        /// <summary>
        /// 判断是否未空
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        private string iSNull(object o)
        {
            if (o is null)
            {
                return "";

            }
            return o.ToString()!;
        }

        private string isNullBool(object o)
        {
            if (o is not null)
            {
                return o.ToString()!;
            }
            return "false";
        }

        private void btnTest_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < dataGridView6.RowCount; i++)
            {
                dataGridView6.Rows[i].Cells[3].Value = "---";
            }

            ProtocolEnum protocol = (ProtocolEnum)Enum.Parse(typeof(ProtocolEnum), cbProtocol.Text, true);

            if (protocol == ProtocolEnum.SiemensS7)
            {
                try
                {
                    string type = iSNull(dgvSiemensPlc.Rows[0].Cells[0].Value);
                    CpuType cpuType = (CpuType)Enum.Parse(typeof(CpuType), type.ToUpper(), true);
                    string ip = iSNull(dgvSiemensPlc.Rows[0].Cells[1].Value);
                    string port = iSNull(dgvSiemensPlc.Rows[0].Cells[2].Value);
                    string rack = iSNull(dgvSiemensPlc.Rows[0].Cells[3].Value);
                    string slot = iSNull(dgvSiemensPlc.Rows[0].Cells[4].Value);

                    Plc plc = new(cpuType, ip, short.Parse(port), short.Parse(rack), short.Parse(slot));
                    plc.Open();

                    for (int i = 0; i < dataGridView6.RowCount; i++)
                    {
                        string alarmAddress = iSNull(dataGridView6.Rows[i].Cells[0].Value);

                        if (alarmAddress.Length < 3)
                        {
                            continue;
                        }
                        dataGridView6.Rows[i].Cells[3].Value = (bool)plc.Read(iSNull(dataGridView6.Rows[i].Cells[0].Value).ToUpper())!;
                    }
                }
                catch (Exception)
                {
                    MessageBox.Show("设备连接失败", "设备连接", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            if (protocol == ProtocolEnum.ModbusTcp)
            {
                try
                {
                    TcpClient client = new TcpClient(iSNull(dGVModbusTcp.Rows[0].Cells[0].Value), int.Parse(iSNull(dGVModbusTcp.Rows[0].Cells[1].Value)));

                    var factory = new ModbusFactory();

                    IModbusMaster master = factory.CreateMaster(client);

                    FunctionBlockEnum func = (FunctionBlockEnum)Enum.Parse(typeof(FunctionBlockEnum), iSNull(dGVModbusTcp.Rows[0].Cells[2].Value), true);

                    byte SlaveAddress = byte.Parse(iSNull(dGVModbusTcp.Rows[0].Cells[3].Value));
                    ushort StartAddress = ushort.Parse(iSNull(dGVModbusTcp.Rows[0].Cells[4].Value));
                    ushort NumberOfPoints = ushort.Parse(iSNull(dGVModbusTcp.Rows[0].Cells[5].Value));

                    IList<bool> bools = new List<bool>();
                    if (func == FunctionBlockEnum.Coils)
                    {
                        //0123456
                        bools = master.ReadCoils(SlaveAddress, (ushort)(StartAddress - 1), NumberOfPoints).ToList();
                    }
                    if (func == FunctionBlockEnum.Inputs)
                    {
                        bools = master.ReadInputs(SlaveAddress, (ushort)(StartAddress - 1), NumberOfPoints).ToList();
                    }

                    int count = dataGridView6.RowCount;

                    for (int i = 0; i < bools.Count; i++)
                    {
                        if (i < count)
                        {
                            dataGridView6.Rows[i].Cells[3].Value = (bool)bools[i];
                        }
                    }

                }
                catch (Exception)
                {
                    MessageBox.Show("设备连接失败", "设备连接", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void dGVModbusTcp_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            ProtocolEnum protocol = (ProtocolEnum)Enum.Parse(typeof(ProtocolEnum), cbProtocol.Text, true);

            if (protocol == ProtocolEnum.ModbusTcp)
            {
                DataGridViewRow row = dGVModbusTcp.Rows[e.RowIndex];

                if (e.ColumnIndex == 5)
                {
                    if (iSNull(dGVModbusTcp.Rows[0].Cells[4].Value).Length >= 1 && iSNull(dGVModbusTcp.Rows[0].Cells[5].Value).Length >= 1)
                    {
                        int len = int.Parse(iSNull(dGVModbusTcp.Rows[0].Cells[5].Value));
                        int num = int.Parse(iSNull(dGVModbusTcp.Rows[0].Cells[4].Value));
                        dataGridView6.Rows.Clear();

                        for (int i = 0; i < len; i++)
                        {
                            int index = dataGridView6.Rows.Add();
                            dataGridView6.Rows[index].Cells[0].Value = num + i;
                        }
                    }
                }
            }
        }

        private void btnImport_Click(object sender, EventArgs e)
        {
            var dialogResult = MessageBox.Show("仅支持 excel\n工作簿：Sheet1\n第一列为：地址栏\n第二列为：报警信息！", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information);

            if (dialogResult != DialogResult.Yes)
            {
                return;
            }

            OpenFileDialog filedialog = new OpenFileDialog();

            filedialog.CheckFileExists = true;

            filedialog.CheckPathExists = true;

            filedialog.Filter = "所有文件(*.*)|*.*"; ;

            DialogResult ret = filedialog.ShowDialog();

            if (ret == DialogResult.OK)
            {
                ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

                using (var package = new ExcelPackage(new FileInfo(filedialog.FileName!)))
                {
                    try
                    {
                        //获取工作簿
                        var sheets = package.Workbook.Worksheets["Sheet1"];
                        //有效行
                        int iRowCount = sheets.Dimension.End.Row;
                        //有效列
                        int colCount = sheets.Dimension.End.Column;
                        dataGridView6.Rows.Clear();
                        dataGridView6.Columns[0].ReadOnly = true;
                        dataGridView6.Columns[1].ReadOnly = true;
                        dataGridView6.AllowUserToAddRows = false;

                        for (int i = 1; i <= iRowCount; i++)
                        {
                            if (sheets.Cells[i, 1].Value != null)
                            {
                                int index = dataGridView6.Rows.Add();
                                dataGridView6.Rows[index].Cells[0].Value = sheets.Cells[i, 1].Value;

                                if (sheets.Cells[i, 2].Value != null)
                                {
                                    dataGridView6.Rows[index].Cells[1].Value = sheets.Cells[i, 2].Value;
                                }
                            }
                        }

                        package.Save();
                    }
                    catch (Exception ex)
                    {
                        package.Save();
                        MessageBox.Show(ex.Message);
                    }
                }
            }
        }
    }
}
